﻿package com.eve.microworld.common.db;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.database.Cursor;

import com.eve.microworld.common.app.BaseApplication;
import com.eve.microworld.common.tools.LogTools;
import com.eve.microworld.common.tools.ComStringTools;

/**
 * 数据库操作类
 * 
 * @author Norsie
 * @created 12-11-28
 * 
 */
public class PersistentUtils {

    static SQLiteAccess mAccess = BaseApplication.getFpiSQLiteAccess ();

    /**
     * 增加新数据
     * 
     * @param model
     */
    public static void addModel ( BaseModel model ) {
        if ( model != null ) {
            mAccess.insert ( BaseModelTool.getTableName ( model.getClass () ) ,
                    BaseModelTool.getContentValues ( model ) );
        }
    }

    /**
     * 删除记录
     * 
     * @param model
     */
    public static void delete ( BaseModel model ) {

        if ( !BaseModelTool.isValidForEditable ( model ) ) {
            LogTools.error ( "数据参数无效，无法进行删除." , null );
            return;
        }
        mAccess.delete ( BaseModelTool.getTableName ( model.getClass () ) ,
                model.getId () );
    }

    /**
     * 更新数据
     * 
     * @param model
     *            数据模型必须是BaseModel的子类；
     */
    public static int update ( BaseModel model ) {
        if ( !BaseModelTool.isValidForEditable ( model ) ) {
            LogTools.error ( "数据无效，无法更新，请检查数据格式。" , null );
        }

        return mAccess.update (
                BaseModelTool.getTableName ( model.getClass () ) ,
                BaseModelTool.getContentValues ( model ) , " id='" + model.getId () +"'", null);

    }

    

    /**
     * 更新数据
     * 
     * @param model
     * @param values
     * @param whereClause
     * @param whereArgs
     * @return
     */
    public static int update(BaseModel model, ContentValues values,
            String whereClause, String[] whereArgs)

    {
        if (!BaseModelTool.isValidForEditable(model)) {
            LogTools.error("数据无效，无法更新，请检查数据格式。", null);
        }

        return mAccess.update(BaseModelTool.getTableName(model.getClass()),
                values, whereClause, whereArgs);

    }
    
    /**
     * 查询数据表获取数据模型列表； 适用于通用模型IdNameModel，此模型不与具体的数据表关联；
     * 
     * @param tableName
     *            数据库表名称
     * @param conditon
     *            查询条件
     * @return 数据模型列表
     */
    public static < T > List < T > getModelList ( Class < ? > modelType ,
            String tableName , String conditon ) {

        List < T > result = new ArrayList < T > ();

        if ( ComStringTools.isEmpty ( tableName ) ) {
            LogTools.error ( "表明为空无法查询数据" , null );
            return result;
        }

        if ( modelType == null ) {
            LogTools.error ( "数据模型的Class为空。" , null );
            return result;
        }

        if ( modelType != null ) {

            Cursor cursor = mAccess.query ( tableName ,
                    BaseModelTool.getNamesForField ( modelType ) , conditon );

            if ( cursor == null ) {
                LogTools.info ( "查询数据库返回的Cursor为空。" );
            }

            T newInstance = null;
            while ( cursor.moveToNext () ) {
                newInstance = ( T ) getModel ( cursor , modelType );
                result.add ( newInstance );
            }

            cursor.close ();
            cursor = null;
        }
        return result;
    }

    /**
     * 查询符合条件的获取对象列表
     * 
     * @param <T>
     *            返回数据类型 与modelType对应
     * @param modelType
     * @param sql
     *            SQLit标准SQL语句
     * @param selectionArgs
     *            sql对应的参数
     * @return
     */
    public static < T > List < T > getModelListBySQL ( Class < ? > modelType ,
            String sql , String [ ] selectionArgs ) {
        List < T > result = new ArrayList < T > ();

        if ( modelType == null ) {
            LogTools.error ( "数据模型的Class为空。" , null );
        }

        if ( modelType != null ) {

            Cursor cursor = mAccess.execRawQuery ( sql , selectionArgs );

            if ( cursor == null ) {
                LogTools.info ( "查询数据库返回的Cursor为空。" );
            }

            while ( cursor.moveToNext () ) {
                T newInstance = ( T ) getModel ( cursor , modelType );
                result.add ( newInstance );
            }

            cursor.close ();
            cursor = null;
        }
        return result;
    }

    /**
     * 查询符合条件的获取对象列表
     * 
     * @param <T>
     * @param modelType
     *            模型类的Class
     * @param conditon
     *            SQL语句中where查询条件之后的条件
     * @return
     */
    public static < T > List < T > getModelList ( Class < ? > modelType ,
            String conditon ) {
        List < T > result = new ArrayList < T > ();

        if ( modelType == null ) {
            LogTools.error ( "数据模型的Class为空。" , null );
        }

        if ( modelType != null ) {

            Cursor cursor = mAccess.query (
                    BaseModelTool.getTableName ( modelType ) ,
                    BaseModelTool.getNamesForField ( modelType ) , conditon );

            if ( cursor == null ) {
                LogTools.info ( "查询数据库返回的Cursor为空。" );
            }

            while ( cursor.moveToNext () ) {
                T newInstance = ( T ) getModel ( cursor , modelType );
                result.add ( newInstance );
            }

            cursor.close ();
            cursor = null;
        }
        return result;
    }

    /**
     * 将cursor中的当前记录按照modelType类型生成对应的对象实例
     * 
     * @param cursor
     *            数据来源，主要取第一行数据
     * @param modelType
     *            要生成的对象类型
     * @return
     */
    public static Object getModel ( Cursor cursor , Class < ? > modelType ) {

        Object newInstance = createInstance ( modelType );

        for ( Field item : BaseModelTool.getFieldList ( modelType ) ) {
            setFieldValue ( newInstance , item , cursor );
        }

        return newInstance;
    }

    /**
     * 设定数据
     * 
     * @param <T>
     * @param newInstance
     * @param item
     * @param cursor
     */
    public static void setFieldValue ( Object newInstance , Field item ,
            Cursor cursor ) {

        String fieldName = item.getName  ();// .toLowerCase ();
        try {
            if ( BaseModelTool.isString ( item ) ) {

                String tmp = cursor.getString ( cursor
                        .getColumnIndex ( fieldName ) );
                //DebugTool.info ( fieldName + " :" + tmp );

                item.set ( newInstance , tmp );
            }
            else if ( BaseModelTool.isLong ( item ) ) {

                item.set ( newInstance ,
                        cursor.getLong( cursor.getColumnIndex ( fieldName ) ) );

            }
            else if( BaseModelTool.isInteger(item))
            {
                item.set(newInstance, cursor.getInt( cursor.getColumnIndex ( fieldName ) ));
            }

        }
        catch ( IllegalStateException e ) {
            LogTools.error ( "无效的字段，无法对应数据库表字段！！" , e );
        }
        catch ( IllegalArgumentException e ) {
            LogTools.error ( " 设置字段的值出错。" , e );
        }
        catch ( IllegalAccessException e ) {
            LogTools.error ( " 设置字段的值出错。" , e );
        }

    }

    /**
     * 创建类实例
     * 
     * @param paramClass
     * @return
     */
    private static Object createInstance ( Class < ? > paramClass ) {

        Object obj = null;
        try {

            obj = paramClass.newInstance ();
        }
        catch ( IllegalAccessException e ) {
            LogTools.error ( "根据类型创建实例异常" , e );
        }
        catch ( InstantiationException e ) {
            LogTools.error ( "根据类型创建实例异常" , e );
        }
        return obj;
    }

    /**
     * 统计记录数
     * 
     * @param modelType
     *            模型类型Class
     * @param conditon
     *            查询条件，标准SQL语句中where 之后的条件。
     * @return
     */
    public static long getRowCount ( Class < ? > modelType , String conditon ) {
        long count = -1;

        String sql = "select count(*) from "
                + BaseModelTool.getTableName ( modelType );
        if ( !ComStringTools.isEmpty ( conditon ) ) {
            sql = sql + " where " + conditon;
        }

        Cursor cursor = mAccess.execRawQuery ( sql , null );
        if ( cursor.moveToNext () ) {
            count = cursor.getLong ( 0 );
            cursor.close ();
            cursor = null;
        }

        return count;
    }
    
    
    
    /**判断数据库是否为空**/
    public static boolean getTableIsNull( Class < ? > modelType){
        /**false  不为空      true 为空*/
        Boolean m = false; 
        if(PersistentUtils.getRowCount (modelType, null ) == 0){
            m = true;
        }
        return  m;
    }

}
